/**
 * 不同页面发包都要记录下viewstate 这是asp.net 遗留下来的问题
 * 因为HTTP是没有状态的
 */

package user;


import enumeration.RobStrategy;
import http.BasicRequest;
import http.util.ParseUtil;
import main.robClass;
import mysql.MysqlUtil;
import okhttp3.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;


public class User implements Runnable {
    private int maxID = Integer.MIN_VALUE;  //extends Thread


    public void startCommonRob() {
        User user = this;
        int accounts = 10;
        //先登录多个账号  获取不同的cookie
        for (int i = 0; i < accounts; i++) {
            user.setUid(i);
            user.login();
        }

        for (int i = 0; i < accounts; i++) {
            user.setUid(i);
            setCommonRob(true);
            Timer timer = new Timer();
            while (user.getViewState() == null) {
                try {
                    user.setViewState(getBasicRequest().getCommonViewState("/xf_xsqxxxk.aspx?xh=" + user.getUsername() + "&xm=" + URLEncoder.encode(user.getStudentName(), "gb2312") + "&gnmkdm=N121203", (getUsername()) + getUid(), getUsername()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("获取到的VS" + user.getViewState());
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            timer.schedule(new TimerTask() {
//                @Override
//                public void run() {
//                    if (isCommonRob()) {
//                        for (int ii = 0; ii < 20; ii++) {
//                            Thread commonCourseThread = new Thread(new CommonCourseThread(user));
//                            commonCourseThread.start();
//
//                        }
//                    }
//                }
//            }, 0, 1000);

        }


    }
//
//    class CommonCourseThread extends Thread {
//        private User user;
//
//        public User getUser() {
//            return user;
//        }
//
//        public void setUser(User user) {
//            this.user = user;
//        }
//
//        public CommonCourseThread(User user) {
//            this.user = user;
//        }
//
//        @Override
//        public void run() {
////            System.out.println("CommonCourseThread.this.user: " + CommonCourseThread.this.user);
////            System.out.println(this.user);
//
//            this.user.robCommonCourse(this.user.getUid());
////            System.out.println(getStudentName() + "--- 开始公选课抢课 --- 当前每秒线程:" + getThreads());
////            setCommonRob(true);
////            if (isCommonRob()) { //判断是否是抢课状态
////                Timer timer = new Timer();
////                timer.schedule(new TimerTask() {
////                    @Override
////                    public void run() {
////                        if (isCommonRob()) {
////                            for (int i = 0; i < getThreads(); i++) {
////                                robCommonCourse(User.this.getUid());
////                            }
////                        }
////                    }
////                }, 0, 100);
////            }
//        }
//    }

    public static LinkedHashSet<String> commonClassViewState = new LinkedHashSet<>();
    public static LinkedHashSet<String> commonClassViewState2 = new LinkedHashSet<>();
    public static LinkedHashSet<String> commonClassViewStateSet = new LinkedHashSet<>();

    public static HashMap<String, String> idToViewState = new HashMap<String, String>();

    public static HashMap<String, User> userCache = new HashMap<>();
    private HashMap<String, String> classCache = new HashMap<>();
    private HashMap<String, String> commonClassCache = new HashMap<>(); //课程代码,选课id
    private String username;
    private String password;
    private String studentName;
    private String startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    private Integer threads = 5;
    private HashSet<String> robClasses = new HashSet<>();

    private HashSet<String> robCommonClasses = new HashSet<>();
    private RobStrategy robStrategy = RobStrategy.ALL;

    private Timer peTimer = new Timer();
    private Timer commonTimer = new Timer();
    private String CommonCourseViewState = null;
    private String viewState = null;
    private String selectedList;

    private BasicRequest basicRequest;
    private int robEnable; //0不加入 1加入抢课所有人列表
    private boolean isPreRob;
    private boolean isRob;
    private boolean isCommonRob;
    private int successCount;
    private int failedCount;
    private int uid;


    public int getRobEnable() {
        return robEnable;
    }

    public void setRobEnable(int robEnable) {
        this.robEnable = robEnable;
    }

    public HashMap<String, String> getCommonClassCache() {
        return commonClassCache;
    }

    public void setCommonClassCache(HashMap<String, String> commonClassCache) {
        this.commonClassCache = commonClassCache;
    }

    public void setCommonCourseViewState(String commonCourseViewState) {
        CommonCourseViewState = commonCourseViewState;
    }

    public String getCommonCourseViewState() {
        return CommonCourseViewState;
    }

    public boolean isCommonRob() {
        return isCommonRob;
    }

    public void setCommonRob(boolean commonRob) {
        isCommonRob = commonRob;
    }

    public boolean isRob() {
        return isRob;
    }

    public void setRob(boolean rob) {
        isRob = rob;
    }

    public boolean isPreRob() {
        return isPreRob;
    }

    public void setPreRob(boolean preRob) {
        isPreRob = preRob;
    }

    public HashMap<String, String> getClassCache() {
        return classCache;
    }

    /**
     * 获取抢课内容后的缓存
     */
    //其实我觉得上个元组会不错?
    // <<课程id>,<,>>
    //考虑到大量查询 我选择线性表ArrayList
    private HashMap<String, HashMap<String, ArrayList<String>>> idToRobClassCache = new HashMap<>();
    private HashMap<String, ArrayList<String>> robClassCache = new HashMap<>();

    public Integer getThreads() {
        return threads;
    }

    public void setThreads(Integer threads) {
        this.threads = threads;
    }

    public String getSelectedList() {
        return selectedList;
    }

    public void setSelectedList(String selectedList) {
        this.selectedList = selectedList;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public HashSet<String> getRobClasses() {
        return robClasses;
    }

    public void setRobClasses(HashSet<String> robClasses) {
        this.robCommonClasses = robClasses;
    }

    public HashSet<String> getRobCommonClasses() {
        return robCommonClasses;
    }

    public void setRobCommonClasses(HashSet<String> robCommonClasses) {
        this.robCommonClasses = robCommonClasses;
    }

    public RobStrategy getRobStrategy() {
        return robStrategy;
    }

    public void setRobStrategy(RobStrategy robStrategy) {
        this.robStrategy = robStrategy;
    }

    @Override
    public String toString() {
        return "User{" +
                "classCache=" + classCache +
                ", commonClassCache=" + commonClassCache +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", studentName='" + studentName + '\'' +
                ", startTime='" + startTime + '\'' +
                ", threads=" + threads +
                ", robClasses=" + robClasses +
                ", robCommonClasses=" + robCommonClasses +
                ", robStrategy=" + robStrategy +
                ", timer=" + peTimer +
                ", CommonCourseViewState='" + CommonCourseViewState + '\'' +
                ", viewState='" + viewState + '\'' +
                ", selectedList='" + selectedList + '\'' +
                ", basicRequest=" + basicRequest +
                ", isPreRob=" + isPreRob +
                ", isRob=" + isRob +
                ", isCommonRob=" + isCommonRob +
                ", successCount=" + successCount +
                ", failedCount=" + failedCount +
                ", uid=" + uid +
                ", idToRobClassCache=" + idToRobClassCache +
                ", robClassCache=" + robClassCache +
                '}';
    }

    public String getStartTime() {
        return startTime;
    }

    public Date getStartTimeDate() {
        Date timestamp = null;
        try {
            timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(this.getStartTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return timestamp;
    }

    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }

    public int getSuccessCount() {
        return successCount;
    }

    public void setSuccessCount(int successCount) {
        this.successCount = successCount;
    }

    public int getFailedCount() {
        return failedCount;
    }

    public void setFailedCount(int failedCount) {
        this.failedCount = failedCount;
    }

    //%D1%A7%C9%FA - 学生
    //%B5%C7+%C2%BC - 登 录
    synchronized
    public void login() {
        System.out.println(getUsername() + " 开始登录");
        String bodyContent = "__VIEWSTATE=dDwxMTE4MjQwNDc1Ozs%2B&TextBox1=" + getUsername() + "&TextBox2=" + getPassword() + "&RadioButtonList1=%D1%A7%C9%FA&Button1=+%B5%C7+%C2%BC+";
        String responseHtml = getBasicRequest().post("/default4.aspx?xh=" + getUsername() + "&" + uid, bodyContent, getUsername() + uid);
        System.out.println("登录的uid为:" + uid);
        //1.先登录 之后根据id 19080101011 19080101012 这样来传给post函数
        String parseResult = ParseUtil.parseScript(responseHtml);
        if (parseResult == null) {
            System.out.println("正方系统 - 登录成功");
            searchClasses();
        }
    }

    synchronized
    public void rob(String classId) {
        //System.out.println("===========rob===========" + (getUsername()) + uid);
        //System.out.println(idToViewState);
        //getSelectedList
        //4%282020-2021-2%29-04TJ08-1908010101%23%282020-2021-2%29-04TJ08-041735-1
        //%D1%A1%B6%A8%BF%CE%B3%CC - 选定课程
        //%CF%EE%C4%BF - 项目
        //System.out.println(robClassCache);
        ArrayList<String> listBox2AndViewState = idToRobClassCache.get((getUsername()) + uid).get(classId);
        //System.out.println("listBox2AndViewState"+listBox2AndViewState);
        //ArrayList<String> listBox2AndViewState = this.robClassCache.get(classId);
        if (listBox2AndViewState == null) {
            return;
        }
        String listBox2 = listBox2AndViewState.get(1);
        //private HashMap<String, HashMap<String, ArrayList<String>>>
        //.filter(z -> z.getKey().equalsIgnoreCase(classId))
        //.flatMap(k -> k.getValue().stream())
        //.findFirst().get();
        //System.out.println("listBox22" + listBox2);
        String viewState = listBox2AndViewState.get(0);
        //根据课名
        //根据cookie

        try {

            //String bodyContent = "__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=" + URLEncoder.encode(viewState, "gb2312") + "&DropDownList1=%CF%EE%C4%BF&ListBox1=" + classId + "&ListBox2=" + URLEncoder.encode(listBox2, "gb2312") + "&RadioButtonList1=0&button3=%D1%A1%B6%A8%BF%CE%B3%CC";

            String bodyContent = "__EVENTTARGET=&__EVENTARGUMENT=" + "&DropDownList1=%CF%EE%C4%BF&ListBox1=" + classId + "&ListBox2=" + URLEncoder.encode(listBox2, "gb2312") + "&RadioButtonList1=0&button3=%D1%A1%B6%A8%BF%CE%B3%CC";
            //String responseHtml = getBasicRequest().postWithLoginCookie("/xstyk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121205", bodyContent);
            String responseHtml = getBasicRequest().postWithLoginCookieAndViewState("/xstyk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121205", bodyContent, (getUsername()) + uid, classId); //VIEWSTATE
            //Integer.valueOf(getUsername()) + uid用来确定cookie与viewstate
            String result = ParseUtil.parseScript(responseHtml);
            String courseName = classCache.entrySet().stream().filter(
                    course -> course.getValue().equalsIgnoreCase(classId)
            ).findFirst().get().getKey();
            System.out.println("Cookie:" + uid + ": " + getStudentName() + " 课程名:" + courseName + " 抢课状态:" + result);
            if (result == null) {
//                System.out.println("检测到抢课状态失败 重新建立TCP连接");
                System.out.println(responseHtml);
                System.out.println("检测到抢课状态失败 取消抢课");
//                setRob(false);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    //    synchronized
//    public HashMap<String, String> searchClasses() {
//
//        String responseHtml = null;
//        try {
//            responseHtml = getBasicRequest().getWithLoginCookie("/xstyk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121205");
//            System.out.println("============searchClasses============");
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//
//        Document doc = Jsoup.parse(responseHtml);
//        Elements options = doc.select("select").select("option[value]");
//        for (int i = 3; i < options.size() - 1; i++) {
//            Element elementClass = options.get(i);
//            String[] text = elementClass.text().split("∥");
//            if (text != null) {
//                classCache.put(text[1], text[0]);
//            }
//        }
//        Element viewStateElement = doc.select("input[name=__VIEWSTATE]").first();
//        if (viewStateElement != null) {
//            setViewState(viewStateElement.val());
//        }
//        System.out.println("查看viewStateElement"+viewStateElement);
//        //<option selected="selected" value="4(2020-2021-2)-04TJ08-1908010101#(2020-2021-2)-04TJ08-041735-1">篮球∥1.0∥彭爱玲∥∥周三第5,6节{第2-19周}∥篮球场2∥40∥∥,2019级会计学,2019级计算机科学与技术,∥广州大学松田学院</option>
//        System.out.println("查看課程緩存"+classCache);
//        return classCache;
//    }
    synchronized
    public HashMap<String, String> searchClasses() {
        System.out.println("============searchClasses============");
        Response response = null;
        String responseHtml = null;
        try {
            response = getBasicRequest().getWithLoginCookie2(
                    "/xstyk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312")
                            + "&gnmkdm=N121205",
                    (getUsername()) + uid); //用来确定cookie

            try {
                responseHtml = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        Document doc = Jsoup.parse(responseHtml);
        Elements options = doc.select("select").select("option[value]");
        for (int i = 3; i < options.size() - 1; i++) {
            Element elementClass = options.get(i);
            String[] text = elementClass.text().split("∥");
            if (text != null) {
                classCache.put(text[1], text[0]);
            }
        }

//        System.out.println("searchClasses-我测试的cookie"+ cookies.toString());
        Element viewStateElement = doc.select("input[name=__VIEWSTATE]").first();
        if (viewStateElement != null) {
            setViewState(viewStateElement.val());
//            idToViewState.put(ii, viewStateElement.val());
//            System.out.println("searchClasses-idToViewState:" + idToViewState);
        }


//        System.out.println("查看viewStateElement" + viewStateElement);
        //<option selected="selected" value="4(2020-2021-2)-04TJ08-1908010101#(2020-2021-2)-04TJ08-041735-1">篮球∥1.0∥彭爱玲∥∥周三第5,6节{第2-19周}∥篮球场2∥40∥∥,2019级会计学,2019级计算机科学与技术,∥广州大学松田学院</option>
//        System.out.println("查看課程緩存" + classCache);
        return classCache;
    }

    //主要是为了获取那个课的viewState状态 以及SelectList 即ListBox2的属性值 4%282020-2021-2%29-04TJ08-1908010101%23%282020-2021-2%29-04TJ08-041735-1
    //我要存储什么信息?
    //课程id 04TJ08
    //ListBox2 ->根据课程来决定的
    //viewState ->来到抢课页面的viewState 它应该也由上面的内容决定
    //className -> 04TJ08
    //%CF%EE%C4%BF - 项目
    synchronized
    public void preRob(String className) {
        String res = null;
        Response response;
//        List<Cookie> cookies = null;
        try {
            String bodyContent = "__EVENTTARGET=ListBox1&__EVENTARGUMENT=&__VIEWSTATE=" + URLEncoder.encode(getViewState(), "gb2312") + "&DropDownList1=%CF%EE%C4%BF&ListBox1=" + className;
            response = getBasicRequest().postWithLoginCookie2(
                    "/xstyk.aspx?xh=" + getUsername() + "&xm=" +
                            URLEncoder.encode(getStudentName(), "gb2312") +
                            "&gnmkdm=N121205", bodyContent,
                    (getUsername()) + uid); //用来决定最终抢课的viewstateList
            try {
                res = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
//            Headers headers = response.headers();
//            System.out.println("cx:" + response.headers());
//            HttpUrl url = response.request().url();
//            cookies = Cookie.parseAll(url, headers);
//            System.out.println("preRob-url:" + url + "cookies:" + cookies);
//            System.out.println("searchClasses-url " + url);
//            cookies = Cookie.parseAll(url, headers);
//            System.out.println("searchClasses中的cookies" + cookies.toString());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        if (res == null) {
            System.out.println("资源初始化失败! 重新获取!");
            preRob(className);
        }
        System.out.println("---------PREROB---------" + (getUsername()) + uid);
        Document doc = Jsoup.parse(res);
        //获取要抢课内容 提前 免得系统蹦了取不回response
        Element selectedListElement = doc.body().select("select[name=ListBox2]").select("option").first();
//        if (selectedListElement == null) {
//            System.out.println("找不到" + selectedListElement);
//            System.out.println(responseHtml);
//            preRob(className);
//        }
        Element viewStateElement = doc.select("input[name=__VIEWSTATE]").first();
        ArrayList<String> listBox2AndViewState = new ArrayList<>();
        if (viewStateElement == null) {
//            System.out.println("找不到" + viewStateElement);
//            System.out.println(res);
            preRob(className);
        }
        if (viewStateElement != null) {

            setViewState(viewStateElement.val());
            listBox2AndViewState.add(getViewState());
            idToViewState.put((getUsername()) + uid + className, viewStateElement.val());
            System.out.println("preRob-idToViewState" + idToViewState);
        }
        if (selectedListElement != null) {
            setSelectedList(selectedListElement.val());
//            preRob(className);
            listBox2AndViewState.add(getSelectedList());
        }

        robClassCache.put(className, listBox2AndViewState);
        idToRobClassCache.put((getUsername()) + uid, robClassCache);
//        System.out.println("preRob-我测试的cookie2" + cookies.toString());

    }

    public BasicRequest getBasicRequest() {
        if (basicRequest == null) {
            basicRequest = new BasicRequest();
        }
        return basicRequest;
    }

    public void setBasicRequest(BasicRequest basicRequest) {
        this.basicRequest = basicRequest;
    }

    public String getViewState() {
        return this.viewState;
    }

    public String getIndexViewState(int index) {
        int i = 0;
        Iterator iterator = commonClassViewState.iterator();
        while (iterator.hasNext()) {
            if (index == i) {
                String s = (String) iterator.next();
                if (s == null) return getRandomViewState();
                return s;
            }
            i++;
        }
        return null;
    }

    public String getRandomViewState() {

        int random = (int) (Math.random() * commonClassViewState.size());
        Iterator iterator = commonClassViewState.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            if (random == i) {
                String s = (String) iterator.next();
                if (s == null) return getRandomViewState();
                return s;
            }
            i++;
        }
        return null;
//        String s = commonClassViewState. (random);
//        if (s == null) {
//            return getRandomViewState();
//        } else {
//            return s;
//        }
    }

    public void setViewState(String viewState) {
        this.viewState = viewState;
    }


    public void stopTimer() {
        if (robClass.robMode == 0) {
            peTimer.cancel();
            System.out.println(getStudentName() + "定时抢体育课 暂停成功!");
        } else {
            commonTimer.cancel();
            System.out.println(getStudentName() + "定时抢公选课 暂停成功!");
        }

    }

    synchronized
    public void startTimer() {
        User user = this;
        if (getStartTimeDate() == null) {
            System.out.println(getStudentName() + " 没有设置抢课时间");
        }
        if (robClass.robMode == 0) {
            peTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(getStudentName() + "定时抢体育课,每秒的检测:");
                    Date date = new Date();
                    //提前十分钟进行资源初始化
                    Date tenMinAdvance = getStartTimeDate();
                    tenMinAdvance.setTime(getStartTimeDate().getTime() - 1000 * 10 * 60);
                    System.out.println(tenMinAdvance);

                    if (!user.isPreRob() && date.after(tenMinAdvance)) {
                        System.out.println("已经超过了抢体育课前10分钟的时间,开始进行资源初始化!");
                        getRobClasses().stream().forEach(course -> preRobs());
                        user.setPreRob(true);
                    }
                    if (date.after(getStartTimeDate())) {
                        System.out.println("已经超过了体育课时间,开始增加抢体育课线程!");
                        startRob();

                        System.out.println("结束抢体育课定时器!");
                        this.cancel();
                    } else {
                        System.out.println("还未到定时抢体育课时间!");
                        System.out.println("目前时间: " + date.toString());
                        System.out.println("定时时间: " + getStartTimeDate());
//                    System.out.println("抢课初始化: " + getRobClassCache().toString());
                    }
                }
            }, 0, 1000);
        } else {
            commonTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(getStudentName() + "定时抢公选课,每秒的检测:");
                    Date date = new Date();
                    //提前十分钟进行资源初始化
                    Date tenMinAdvance = getStartTimeDate();
                    tenMinAdvance.setTime(getStartTimeDate().getTime() - 2000 * 10 * 60);
                    System.out.println(tenMinAdvance);
                    if (!user.isPreRob() && date.after(tenMinAdvance)) {
                        System.out.println("已经超过了抢课前10分钟的时间,开始进行资源初始化!");
                        user.setCommonRob(true);
                        preRobs();
                        setPreRob(true);
                        user.setPreRob(true);
                    }

                    if (date.after(getStartTimeDate())) {
                        System.out.println("已经超过了抢公选课时间,开始增加抢公选课线程!");
                        MysqlUtil.getUsers(user).parallelStream().forEach(user2 -> {
                            user2.startRob();
                        });
                        System.out.println("结束抢公选课定时器!");
                        this.cancel();
                    } else {
                        System.out.println("还未到定时抢公选课时间!");
                        System.out.println("目前时间: " + date.toString());
                        System.out.println("定时时间: " + getStartTimeDate());
//                    System.out.println("抢课初始化: " + getRobClassCache().toString());
                    }
                }
            }, 0, 1000);
        }
    }

    public HashMap<String, ArrayList<String>> getRobClassCache() {
        return robClassCache;
    }

    public void setRobClassCache(HashMap<String, ArrayList<String>> robClassCache) {
        this.robClassCache = robClassCache;
    }

    public void outPutRobs() {
        System.out.println("确定抢体育课列表: ");
        for (String robClass : getRobClasses()) {
            Optional<Map.Entry<String, String>> courseNameAndId = getClassCache().entrySet().stream().filter(
                    course -> course.getValue().equalsIgnoreCase(robClass)
            ).findFirst();
            if (courseNameAndId.isPresent()) {
                System.out.println(courseNameAndId.get().getKey());
            }
        }
    }

    public void outPutCommonRobs() {
        System.out.println("确定抢公选课列表: ");
        for (String robClass : getRobClasses()) {
            Optional<Map.Entry<String, String>> courseNameAndId = getCommonClassCache().entrySet().stream().filter(
                    course -> course.getValue().equalsIgnoreCase(robClass)
            ).findFirst();
            if (courseNameAndId.isPresent()) {
                System.out.println(courseNameAndId.get().getKey());
            }
        }
    }

    public void preRobs() {
        if (robClass.robMode == 0) { //体育课模式

            login();//传入id 方便初始化cookie idAndcookies

            //登录后id绑定cookie
            searchClasses();
            //搜索课程 不需要cookie
            boolean x = true;
//        AtomicInteger i = new AtomicInteger();
            while (getViewState() != null && x) {
                System.out.println("**********preRobs**********");
                getRobClasses().parallelStream().forEach(course ->
                        preRob(course)
                );
                //开始预备资源 需要id获取cookie发包
                setPreRob(true);
                x = false;
            }
        } else { //公选课模式
            MysqlUtil.getUsers(this).parallelStream().forEach(user3 -> {
                user3.login();
                user3.testInit();
            });
            setPreRob(true);
        }

    }


    public void stopRob() {
        setRob(false);
        System.out.println("停止抢课");
    }

    //    synchronized
    synchronized
    public void startRob() {
        User user = this;
        Random random = new Random();
        if (robClass.robMode == 0) {
            for (int i = 0; i < robClass.num; i++) {
                user.setUid(i);
                preRobs();
            }
            System.out.println(getStudentName() + "开始抢课 --- 当前每秒线程:" + getThreads());
            setRob(true);
            if (isRob()) {
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        if (isRob()) {
                            for (int i = 0; i < getThreads(); i++) {
                                Thread thread = new Thread(user);
                                user.setUid(random.nextInt(robClass.num));
                                thread.start();
                            }
                        }
                    }
                }, 0, 1000);

            }
        }

        if (robClass.robMode == 1) {
            int accounts = 5;
            try {
                setViewState(getBasicRequest().getCommonViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", (getUsername()) + uid, getUsername()));
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (getCommonCourseViewState() == null) {
                try {
                    String bodyContent = "__EVENTTARGET=dpkcmcGrid%3AtxtPageSize&__EVENTARGUMENT=&ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=&Button2=%C8%B7%B6%A8&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150";
                    String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + uid, getUsername(), getViewState());
                    setCommonCourseViewState(getBasicRequest().getCommonViewStateByHtml(responseHtml));
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            setCommonRob(true);
            if (isCommonRob()) {
                Timer timer2 = new Timer();
                timer2.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        if (isCommonRob()) {
                            for (int i = 0; i < 3; i++) {
                                Thread thread = new Thread(user);
                                thread.start();
                            }
                        }
                    }
                }, 0, 1000);
            }
        }

    }

    //新建抢课子线程
    @Override
    public void run() {
        if (isRob()) {
            this.getRobClasses().stream().forEach(course -> {
                this.rob(course);
            });
        }
        if (isCommonRob()) {
            if (getUsername().equalsIgnoreCase("1805030124")) {
                this.initExtraCommonCourseViewState();
            }
            this.initCommonCourseViewState();
        }
    }

    /*公选课部分的代码*/
    public void stopCommonRob() {
        setCommonRob(false);
        System.out.println("停止公选抢课");
    }

    synchronized
    public HashMap<String, String> searchCommonClasses(boolean display) {
        if (display) {
            System.out.println("============寻找公选课============");
        }

        HashMap<String, String> commonClasses = new HashMap<>();

        String responseHtml = null;
        try {
            setViewState(getBasicRequest().getCommonViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", (getUsername()) + uid, getUsername()));
            String bodyContent = "__EVENTTARGET=dpkcmcGrid%3AtxtPageSize&__EVENTARGUMENT=&ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=&Button2=%C8%B7%B6%A8&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150";
            responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + uid, getUsername(), getViewState());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Document doc = Jsoup. parse(responseHtml);
        Elements options = doc.select("span[class=formbox]").select("tbody").select("tr");
        for (int i = 1; i < options.size() - 1; i++) {
            Element elementClass = options.get(i);
            Elements tds = elementClass.select("td");
//            System.out.println(tds.get(2).html());
            if(tds.size() > 1) {
                if (!tds.get(2).html().contains("学分")) {
                    String className = tds.get(2).html().split("</a>")[0].split(">")[1];
                    String classCode = tds.get(3).html().split("</td>")[0];
                    String postValue = tds.get(0).html().split("name=\"")[1].split("\"")[0];
                    String time = tds.get(5).html().split("</td>")[0];
                    String hiddenCode = tds.get(2).html().split("</a>")[0].split("xkkh=")[1].split("'")[0];
                    if (display) {
                        System.out.println("========================================");
                        System.out.println("课程名字: " + className);
                        System.out.println("课程代码: " + classCode);
                        System.out.println("上课时间: " + time);
                        System.out.println("发包数据: " + postValue);
                        System.out.println("隐藏代码: " + tds.get(2).html().split("</a>")[0].split("xkkh=")[1].split("'")[0]);
                    }

                    commonClasses.put(hiddenCode, postValue);
//            commonClasses.put(classCode, postValue);
                }
            }

        }
        setCommonClassCache(commonClasses);

        return getCommonClassCache();
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    synchronized
    public void preRobCommons() throws IOException {
        System.out.println("**********preRobCommons**********");
        String VW = null;
        VW = getBasicRequest().getCommonViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", getUsername() + uid, getUsername());
        setViewState(VW);
        commonClassViewState.add(VW);

        for (int i = 1; i < 10; i++) {
            setUid(i);
            login(); //确保有COOKIE
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("添加的: " + getViewState());
            commonClassViewState2.add(getViewState());
            String bodyContent = "ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=&kcmcGrid%3A_ctl2%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl3%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl4%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl5%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl6%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl7%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl8%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl9%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl10%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl11%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl12%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl13%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl14%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl15%3Axk=on&kcmcGrid%3A_ctl15%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl16%3Axk=on&kcmcGrid%3A_ctl16%3Ajcnr=%7C%7C%7C&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=15&Button1=++%CC%E1%BD%BB++";
            String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + (i), getUsername(), getViewState());
            //String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + (i), getUsername(), getRandomViewState());

            String VW2 = BasicRequest.getCommonViewStateByHtml(responseHtml);
            setViewState(VW2);
            commonClassViewState.add(VW2);
            System.out.println("第" + i + "次加的VW2: " + VW2);
            try {
                Thread.sleep(3100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    synchronized
    public void robCommonCourse(int uid) {
        try {
            if (this.getViewState() != null) {
                String bodyContent = "ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=&kcmcGrid%3A_ctl2%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl3%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl4%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl5%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl6%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl7%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl8%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl9%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl10%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl11%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl12%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl13%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl14%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl15%3Axk=on&kcmcGrid%3A_ctl15%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl16%3Axk=on&kcmcGrid%3A_ctl16%3Ajcnr=%7C%7C%7C&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150&Button1=++%CC%E1%BD%BB++";
                String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + uid, getUsername(), this.getViewState());
                if (responseHtml != null) {
                    String vs = BasicRequest.getCommonViewStateByHtml(responseHtml);
                    if (vs != null) setViewState(vs);
                    Document doc = Jsoup.parse(responseHtml);
                    System.out.println(responseHtml);
                    if (doc != null) {
                        Elements alert = doc.select("script");
                        if (alert != null) {
                            for (int i = 0; i < 2; i++) {
                                if (alert.size() > 0) {
                                    if (alert.get(i) != null) {
                                        System.out.println(alert.get(i).html().split("alert\\('")[1].split("'")[0]);
                                    }
                                }

                            }
                        }
                    }
                }
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    synchronized
    public void initCommonCourseViewState() {
        try {
            if (getCommonCourseViewState() != null) {
//                bodyContent = bodyContent + "&" + URLEncoder.encode(getCommonClassCache().get(courseId), "gb2312") + "=on";

                String bodyContent = "ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=";
                StringBuilder sb = new StringBuilder(bodyContent);
                for (int i = 2; i <= 42; i++) {
                    boolean xk = false;
                    for (String courseId : getRobCommonClasses()) {
                        Integer num2 = Integer.valueOf(getCommonClassCache().get(courseId).split(":")[1].split(":")[0].split("ctl")[1]);
                        if (i == num2) {
                            sb.append("&" + URLEncoder.encode(getCommonClassCache().get(courseId), "gb2312") + "=on");
                            xk = true;
                            break;
                        }
                    }
                    if (!xk) {
                        sb.append("&kcmcGrid%3A_ctl" + i + "%3Ajcnr=%7C%7C%7C");
                    }
                }

//                for (int i = 2; i <= 42; i++) {
//                    boolean xk = false;
//                    for (String courseId : getRobCommonClasses()) {
//                        Integer num2 = Integer.valueOf(getCommonClassCache().get(courseId).split(":")[1].split(":")[0].split("ctl")[1]);
//                        //System.out.println("num2:" + num2);
//                        if (i == num2) {
////                            bodyContent = bodyContent + "&kcmcGrid%3A_ctl" + i + "%3Axk=on";
//                            bodyContent = bodyContent+ "&" + URLEncoder.encode(getCommonClassCache().get(courseId), "gb2312") + "=on";
//                            xk = true;
//                            break;
//                        }
//                    }
//                    if (!xk) {
//                        bodyContent = bodyContent + "&kcmcGrid%3A_ctl" + i + "%3Ajcnr=%7C%7C%7C";
//                    }
//                }
//                bodyContent = bodyContent + "&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150&Button1=++%CC%E1%BD%BB++";
                bodyContent = sb.toString() + "&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150&Button1=++%CC%E1%BD%BB++";
//                System.out.println(bodyContent);
//                String bodyContent = "ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBo0x1=&kcmcGrid%3A_ctl2%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl3%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl4%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl5%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl6%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl7%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl8%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl9%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl10%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl11%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl12%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl13%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl14%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl15%3Axk=on&kcmcGrid%3A_ctl15%3Ajcnr=%7C%7C%7C&kcmcGrid%3A_ctl16%3Axk=on&kcmcGrid%3A_ctl16%3Ajcnr=%7C%7C%7C&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150&Button1=++%CC%E1%BD%BB++";
//                System.out.println(bodyContent);
                String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + uid, getUsername(), getCommonCourseViewState());
                if (responseHtml != null) {
                    if (BasicRequest.getCommonViewStateByHtml(responseHtml) != null) {
                        setCommonCourseViewState(BasicRequest.getCommonViewStateByHtml(responseHtml));
                    }
                    Document doc = Jsoup.parse(responseHtml);
                    Elements alert = doc.select("script");
                    //System.out.println(responseHtml);
                    if (alert != null) {
                        for (int ii = 0; ii < 2; ii++) {
                            if (alert.get(ii).html() != null) {
                                if (alert.get(ii).html().split("alert\\('").length > 1) {
                                    System.out.println(getStudentName() + " " + alert.get(ii).html().split("alert\\('")[1].split("'")[0]);
                                }

                            }
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();

        }

        /*
        String courseName = classCache.entrySet().stream().filter(
        course -> course.getValue().equalsIgnoreCase(classId)
        ).findFirst().get().getKey();
        System.out.println("Cookie:" + uid + ": " + getStudentName() + " 课程名:" + courseName + " 抢课状态:");
        */
    }

    public static LinkedHashSet<String> getCommonClassViewStateSet() {
        return commonClassViewStateSet;
    }

    public static void setCommonClassViewStateSet(LinkedHashSet<String> commonClassViewStateSet) {
        User.commonClassViewStateSet = commonClassViewStateSet;
    }

    public void startPreCommonRob() throws InterruptedException {

        Timer timer2 = new Timer();
        timer2.schedule(new TimerTask() {
            @Override
            public void run() {
                for (int i = 0; i < 300; i++) {
                    Thread preCommonCourseThread = new Thread(new preCommonCourseThread(), String.valueOf(getUsername() + (i % 20)) + String.valueOf(i));
                    preCommonCourseThread.start();
                }
            }
        }, 0, 5000);


    }

    class preCommonCourseThread extends Thread {
        @Override
        public void run() {
            initCommonCourseViewState();
        }
    }

    synchronized
    public void testInit() {
        searchCommonClasses(false);
        if (getViewState() == null) {
            try {
                setViewState(getBasicRequest().getCommonViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", (getUsername()) + uid, getUsername()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (getCommonCourseViewState() == null) {
            try {
                String bodyContent = "__EVENTTARGET=dpkcmcGrid%3AtxtPageSize&__EVENTARGUMENT=&ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=&Button2=%C8%B7%B6%A8&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150";
                String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + uid, getUsername(), getViewState());
                setCommonCourseViewState(getBasicRequest().getCommonViewStateByHtml(responseHtml));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

//
//        ArrayList<Integer> nums = new ArrayList<>();
//
//        for (String courseId : getRobCommonClasses()) {
//
//            Integer num = Integer.valueOf(getCommonClassCache().get(courseId).split(":")[1].split(":")[0].split("ctl")[1]);
//            System.out.println("num: " + num);
//            if (num > this.maxID) {
//                this.maxID = num;
//            }
//            nums.add(num);
//        }


    }


    synchronized
    public void initExtraCommonCourseViewState() {
        try {
            if (getCommonCourseViewState() != null) {
                String bodyContent = "ddl_kcxz=&ddl_ywyl=%D3%D0&ddl_kcgs=&ddl_xqbs=1&ddl_sksj=&TextBox1=";
                StringBuilder sb = new StringBuilder(bodyContent);
                for (int i = 2; i <= 42; i++) {
                    Integer num2 = Integer.valueOf(getCommonClassCache().get("(2020-2021-2)-08016X-081793-1").split(":")[1].split(":")[0].split("ctl")[1]);
                    if (i == num2) {
                        sb.append("&" + URLEncoder.encode(getCommonClassCache().get("(2020-2021-2)-08016X-081793-1"), "gb2312") + "=on");
                        break;
                    } else {
                        sb.append("&kcmcGrid%3A_ctl" + i + "%3Ajcnr=%7C%7C%7C");
                    }
                }

                bodyContent = sb.toString() + "&dpkcmcGrid%3AtxtChoosePage=1&dpkcmcGrid%3AtxtPageSize=150&Button1=++%CC%E1%BD%BB++";
//                System.out.println(bodyContent);
                String responseHtml = getBasicRequest().postCommonWithLoginCookieAndViewState("/xf_xsqxxxk.aspx?xh=" + getUsername() + "&xm=" + URLEncoder.encode(getStudentName(), "gb2312") + "&gnmkdm=N121203", bodyContent, (getUsername()) + uid, getUsername(), getCommonCourseViewState());
                if (responseHtml != null) {
                    if (BasicRequest.getCommonViewStateByHtml(responseHtml) != null) {
                        setCommonCourseViewState(BasicRequest.getCommonViewStateByHtml(responseHtml));
                    }
                    Document doc = Jsoup.parse(responseHtml);
                    Elements alert = doc.select("script");
                    if (alert != null) {
                        for (int ii = 0; ii < 2; ii++) {
                            if (alert.get(ii).html() != null) {
                                if (alert.get(ii).html().split("alert\\('").length > 1) {
                                    System.out.println(getStudentName() + " " + alert.get(ii).html().split("alert\\('")[1].split("'")[0]);
                                }

                            }
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();

        }

        /*
        String courseName = classCache.entrySet().stream().filter(
        course -> course.getValue().equalsIgnoreCase(classId)
        ).findFirst().get().getKey();
        System.out.println("Cookie:" + uid + ": " + getStudentName() + " 课程名:" + courseName + " 抢课状态:");
        */
    }

}

